{% extends 'base.html' %}
{% load static %}
{% block title %}
    <h2>任务面板</h2>
{% endblock %}
{% block content %}
    <style>
        #output-container {
            height: 100%;
        {#width: 550px;#} border: 1px solid #ccc;
            background-color: #1e1e1e; /* 类似终端黑底 */
            color: #00ff00;
            font-family: "Courier New", Courier, monospace;
            overflow-y: auto;
            padding: 10px;
            box-sizing: border-box;
        {#display: none;#}
        }

        .code-demo {
            height: 100%;
        {#width: 550px;#} border: 1px solid #ccc;
            background-color: #1e1e1e; /* 类似终端黑底 */
            color: #00ff00;
            font-family: "Courier New", Courier, monospace;
            overflow-y: auto;
            padding: 10px;
            box-sizing: border-box;
        }

        #host_tables {
            height: 550px;
            overflow-y: auto;
        }


    </style>

    <div class="layui-fluid">

        <div class="layui-row layui-col-space30">

            <div id="host_tables" class="layui-col-xs12">
                <form class="layui-form  layui-col-space10 ">
                    <div class="layui-col-md4">
                        <div class="layui-input-wrap">

                            <input type="text" name="host_search" value="" placeholder="任务名称"
                                   class="layui-input"
                                   lay-affix="clear">
                        </div>
                    </div>
                    <div class="layui-btn-container layui-col-xs12 layui-col-md4">
                        <button class="layui-btn" lay-submit lay-filter="table-search">搜索</button>
                        <button type="reset" class="layui-btn layui-btn-primary">清空</button>

                    </div>
                </form>
                <table class="layui-hide" id="job_list" lay-filter="job_list"></table>
            </div>

        </div>

    </div>



    <script>
        let csrftoken = null;
        var globalTaskId;

        // 独立日志系统
        var taskLogs = {}; // {job_id: [...], job_id: [...]}
        var activeTasks = {}; // {taskId: socket}

        // 获取csrf
        $.ajax({
            url: '{% url 'ansible_run:get_csrf_token' %}', // 替换为你的实际地址
            method: 'GET',
            async: false, // 注意：这里设置为同步请求，确保token获取完成后再继续执行
            success: function (response) {
                {#console.log(response)#}
                csrftoken = response.csrfToken; // 假设后端返回的数据结构是 {'csrf_token': 'your-csrf-token'}
            },
            error: function (xhr, status, error) {
                console.error('Error fetching CSRF token:', error);
            }
        });

        // 创建WebSocket连接
        function createWebSocket(task_id, job_id, containerId) {
            console.log("为任务创建WebSocket:", task_id, containerId);

            // 初始化该任务的日志数组
            if (!taskLogs[job_id]) {
                taskLogs[job_id] = [];
            }

            // 获取日志容器
            var outputContainer = document.getElementById(containerId);
            if (!outputContainer) {
                console.error("未找到输出容器:", containerId);
                return;
            }

            // 关闭已存在的连接（如果有）
            if (activeTasks[task_id]) {
                activeTasks[task_id].close();
                delete activeTasks[task_id];
            }

            // 显示连接状态
            outputContainer.innerHTML = '<div style="color:#aaa">正在连接日志服务器...</div>';

            // 建立WebSocket连接
            const socket = new WebSocket("ws://192.168.56.142:8000/ws/task/" + task_id);
            activeTasks[task_id] = socket; // 存储连接

            socket.onopen = function () {
                outputContainer.innerHTML = '<div style="color:#4CAF50">连接成功，开始接收日志...</div><hr>';

                // 显示该任务已有的日志
                renderCachedLogs(job_id, outputContainer);
            };

            socket.onmessage = function (event) {
                try {
                    var jsonObject = JSON.parse(event.data);

                    // 创建日志条目
                    var logEntry = {
                        content: jsonObject['stdout'],
                        status: jsonObject.status,
                        timestamp: new Date().toISOString()
                    };

                    // 保存到该任务的日志数组
                    taskLogs[job_id].push(logEntry);

                    // 如果日志窗口已打开，实时显示
                    renderLogEntry(logEntry, outputContainer);

                } catch (e) {
                    console.error("JSON 解析失败:", event.data);
                }
            };

            socket.onclose = function () {
                outputContainer.innerHTML += '<div style="color:#999">连接已关闭</div>';
                delete activeTasks[task_id];
            };

            socket.onerror = function (error) {
                outputContainer.innerHTML += '<div style="color:#ff4d4d">连接错误: ' + error.message + '</div>';
                delete activeTasks[task_id];
            };
        }

        // 渲染特定任务的缓存日志
        function renderCachedLogs(job_id, container) {
            console.log(taskLogs)
            if (!taskLogs[job_id] || taskLogs[job_id].length === 0) {
                container.innerHTML = '<div style="color:#aaa">无历史日志记录</div>';
                return;
            }

            container.innerHTML = ''; // 清空容器

            // 添加标题显示历史日志
            var historyHeader = document.createElement("div");
            historyHeader.innerHTML = '<div style="color:#ccc; border-bottom:1px solid #444; margin-bottom:10px">----------------- 历史日志 -----------------</div>';
            container.appendChild(historyHeader);

            // 渲染该任务的所有日志
            taskLogs[job_id].forEach(function (logEntry) {
                renderLogEntry(logEntry, container);
            });
        }

        // 渲染日志到页面
        function renderLogEntry(logEntry, container) {
            var line = document.createElement("div");
            line.className = "log-line";
            line.textContent = logEntry.content;

            // 设置不同状态的显示颜色
            if (logEntry.status === "runner_on_unreachable" ||
                logEntry.status === "runner_on_failed") {
                line.style.color = "#ff4d4d";
            } else if (logEntry.status === "runner_on_ok") {
                line.style.color = "#16b777";
            } else {
                line.style.color = "#00ff00"; // 默认颜色
            }

            container.appendChild(line);
        }

        layui.use(['table'], function () {
            var table = layui.table;
            var form = layui.form
            var dropdown = layui.dropdown;
            var util = layui.util;


            table.render({
                elem: '#job_list',
                url: '{% url 'runner_jobs:job-list' %}',
                page: true,
                limits: [5, 10, 50, 100, 200],
                toolbar: `
                <div>
                <button type="button" id="left_toolbar_create_jobs"  lay-event="left_toolbar_create_jobs" class="layui-btn layui-btn-sm">创建任务</button>
                <button type="button" id="left_toolbar_delete_jobs"  lay-event="left_toolbar_delete_jobs" class="layui-btn layui-btn-sm layui-bg-red">批量删除</button>
                </div>

                `,
                cols: [[
                    {type: 'checkbox', fixed: 'left'},
                    {field: 'job_name', title: '任务名称',},
                    {field: 'job_type', title: '任务类型'},
                    {
                        title: "操作",
                        templet: function (d) {
                            // d 是当前行的数据对象，d.id 就是主键
                            return `
                           <button lay-event="run_jobs"  class="layui-btn layui-btn-xs" >执行</button>
                            <button lay-event="stop_jobs"  class="layui-btn layui-btn-xs layui-bg-red">停止</button>
                            <button lay-event="logs"  class="layui-btn layui-btn-xs layui-bg-blue">实时日志</button>

                             <button class="layui-btn layui-btn-xs layui-bg-blue" lay-event="more">
                              更多
                              <i class="layui-icon layui-icon-down"></i>

                            </button>




                        `
                        }
                    }
                ]]

            })
            // 表头按钮事件
            table.on('toolbar(job_list)', function (obj) {
                // 创建任务
                if (obj.event == 'left_toolbar_create_jobs') {
                    layer.open({
                        type: 2, // page 层类型
                        area: ['1100px', '700px'],
                        title: '任务创建',
                        scrollbar: false,
                        maxmin: true, // 允许全屏最小化
                        content: '{% url 'runner_jobs:go_jobs' %}',
                        end: function () {
                            // 在这里重载表格
                            layui.table.reload('job_list'); // 'test' 是你 table.render({ elem: "#test" }) 中的 elem ID
                        }
                    });
                }

                if (obj.event == 'left_toolbar_delete_jobs') {
                    var id = obj.config.id;
                    var checkStatus = table.checkStatus(id);
                    let list = checkStatus.data
                    let selectedIds = []
                    for (let i = 0; i < list.length; i++) {
                        selectedIds.push(list[i].job_id)
                    }

                    if (selectedIds.length > 0) {
                        // 确认删除
                        layer.confirm('确定要删除选中的 ' + selectedIds.length + ' 任务吗？', {
                            icon: 3,
                            title: '批量删除确认',
                            btn: ['确定删除', '取消']
                        }, function (index) {
                            // 发送AJAX请求
                            $.ajax({
                                url: '{% url "runner_jobs:batch_delete_jobs_api" %}',
                                type: 'POST',
                                data: {
                                    'job_ids[]': selectedIds,
                                    'csrfmiddlewaretoken': '{{ csrf_token }}'
                                },
                                success: function (response) {
                                    if (response.status === 'success') {
                                        layer.msg(response.message, {icon: 1});
                                        // 刷新表格
                                        layui.table.reload('job_list');
                                    } else {
                                        layer.msg(response.message, {icon: 2});
                                    }
                                },
                                error: function () {
                                    layer.msg('删除请求失败', {icon: 2});
                                }
                            });
                            layer.close(index);
                            layui.table.reload('job_list');
                        });
                    } else {
                        layer.msg('未选择任务', {icon: 2});
                    }

                }
            })
            // 单元格事件
            table.on('tool(job_list)', function (obj) {

                // 实时日志查看
                if (obj.event == 'logs') {
                    // 获取当前行的任务ID
                    job_id = obj.data.job_id
                    console.log(obj.data.task_id)
                    // 为该任务创建唯一标识
                    var uniqueId = 'output-container-' + globalTaskId;
                    task_id_data = JSON.stringify(
                        {
                            taskId: obj.data.task_id
                        }
                    )

                    layer.open({
                        type: 1,
                        offset: 'r',
                        anim: 'slideLeft',
                        move: false,
                        area: ['620px', '100%'],
                        title: '任务日志 - ' + obj.data.job_name + ' <button class="layui-btn layui-btn-xs layui-bg-red" type="button" onclick="stopjob(task_id_data)">停止任务</button>',
                        content: '<pre class="layui-code code-demo" id="' + uniqueId + '">正在连接日志服务器...</pre>',
                        shadeClose: true,
                        success: function () {

                            setTimeout(() => {
                                // 先显示缓存的日志
                                var container = document.getElementById(uniqueId);
                                renderCachedLogs(job_id, container);
                                // 如果任务还在运行，建立连接获取实时日志
                                if (activeTasks[globalTaskId]) {
                                    createWebSocket(globalTaskId, job_id, uniqueId);

                                }
                            }, 100);
                        }
                    });
                }

                // 执行任务
                if (obj.event == 'run_jobs') {

                    $.ajax({
                        url: '{% url 'ansible_run:ansible_run' %}',
                        method: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify(obj.data),
                        headers: {
                            'X-CSRFToken': csrftoken // 在这里使用获取到的token
                        },
                        success: function (res) {
                            obj.update({
                                task_id: res['task_id'],
                            });
                            globalTaskId = res['task_id'];
                            job_id = obj.data.job_id
                            console.log(obj)
                            // 初始化该任务的日志存储
                            taskLogs[job_id] = [];
                            task_id_data = JSON.stringify(
                                {
                                    taskId: res['task_id']
                                }
                            )

                            console.log(task_id_data)
                            {#wbsocket(res['task_id'], index)#}
                            // 立即打开日志窗口
                            var uniqueId = 'output-container-' + globalTaskId;
                            {#createWebSocket(globalTaskId, job_id, uniqueId);#}
                            layer.open({
                                type: 1,
                                offset: 'r',
                                anim: 'slideLeft',
                                area: ['620px', '100%'],
                                move: false,
                                title: '任务日志 - ' + obj.data.job_name + ' <button class="layui-btn layui-btn-xs layui-bg-red" type="button" onclick="stopjob(task_id_data)">停止任务</button>',
                                content: '<pre class="layui-code code-demo" id="' + uniqueId + '">正在启动任务...</pre>',
                                shadeClose: true,
                                success: function () {
                                    createWebSocket(globalTaskId, job_id, uniqueId);
                                }
                            });

                        },
                        error: function (xhr) {
                            alert('提交失败：' + (xhr.responseJSON?.error || '请检查输入'));
                        }
                    });
                }
                // 停止任务
                if (obj.event == 'stop_jobs') {

                    data = JSON.stringify(
                        {
                            taskId: globalTaskId
                        }
                    )
                    stopjob(data)

                } else if (obj.event === 'more') {
                    // 更多 - 下拉菜单
                    dropdown.render({
                        elem: this, // 触发事件的 DOM 对象
                        show: true, // 外部事件触发即显示
                        data: [{
                            title: '查看',
                            id: 'detail'
                        }, {
                            title: '删除',
                            id: 'del'
                        }],
                        click: function (menudata) {
                            // 任务详情
                            if (menudata.id === 'detail') {
                                layer.open({
                                    type: 2, // page 层类型
                                    area: ['700px', '600px'],
                                    title: '任务详情',
                                    scrollbar: false,
                                    maxmin: true, // 允许全屏最小化
                                    content: '/runner_jobs/jobs/' + obj.data.job_id,
                                    end: function () {
                                        // 在这里重载表格
                                        layui.table.reload('job_list'); // 'job_list' 是你 table.render({ elem: "#job_list" }) 中的 elem ID
                                    }
                                });
                            } else if (menudata.id === 'del') {
                                // 删除任务
                                if (confirm('确定要删除吗？')) {  // 原生 confirm 弹窗
                                    // 发送 AJAX DELETE 请求
                                    $.ajax({
                                        url: `/runner_jobs/api/jobs/delete/${obj.data.job_id}/`,
                                        method: 'DELETE',
                                        success: function () {
                                            alert('任务已删除');
                                            layui.table.reload('job_list');
                                        }
                                    });
                                }

                            }
                        },
                        id: 'dropdown-table-tool',
                        align: 'right', // 右对齐弹出
                        style: 'box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);' // 设置额外样式
                    });
                }
            })            // 搜索
            form.on('submit(table-search)', function (data) {
                var field = data.field; // 获得表单字段
                console.log(field)
                // 执行搜索重载
                table.reload('job_list', {
                    page: {
                        curr: 1 // 重新从第 1 页开始
                    },
                    where: field // 搜索的字段
                });
                return false; // 阻止默认 form 跳转
            });

        })

        function stopjob(data) {

            $.ajax({
                url: '{% url 'ansible_run:cancel_task_api' %}',
                method: 'POST',
                contentType: 'application/json',
                data: data,
                headers: {
                    'X-CSRFToken': csrftoken // 在这里使用获取到的token
                },
                success: function (res) {

                    globalTaskId = 'None'
                },
                error: function (xhr) {
                    alert('提交失败：' + (xhr.responseJSON?.error || '请检查输入'));
                }
            });
        }

    </script>
{% endblock %}

